/**
 * 第二步
 * 实验设计添加试剂架和试管架
 *
 */
import { FC, useEffect, useMemo, useState } from "react";
import { observer, inject } from "mobx-react";
import { useParams, useNavigate } from "react-router-dom";
import {
  Layout,
  Divider,
  Select,
  Popover,
  Descriptions,
  Spin,
  Modal,
  Typography,
  Space,
  Row,
  Col,
  Button,
  message,
} from "antd";
import {
  createList,
  ROWWORD,
  RROWWORD,
  BASEWIDE,
  BASEHEIGHT,
  RATE,
  MARGIN,
  ReactionSlotName,
} from "../../utils";
import StepTop from "./StepTop";
import ShelfMiniPlane from "./ShelfMiniPlane";
// import PlaneImages from "./PlaneImages"
import { ITStore } from "../../store";
import { ITShelf, ITBottle, ITDictValue } from "../../store/interfaces";
import "../Workbench/index.less";

interface TProp {
  store: ITStore;
}

interface ITDWP extends TProp {
  setShowShelfModal: (data: boolean) => void;
  setShowReactModal: (data: boolean) => void;
  setSlotName: (data: string) => void;
}

interface ITShelfModal extends ITDWP {
  showShelfModal: boolean;
  slotName: string;
  close: () => void;
}

interface ITPopCont {
  store: ITStore;
  allShelf: ITShelf[];
  label: string;
}

interface ITRPopCont extends ITDWP {
  showReactModal: boolean;
  slotName: string;
  close: () => void;
}

interface ITRSProp extends TProp {
  slotName: string;
  showModal: boolean;
  close: () => void;
}

interface ITShelfBottle {
  shelfInfo?: ITShelf | null;
  bottleInfo?: ITBottle | null;
}

const { Content } = Layout;
const { Option } = Select;
const { Text } = Typography;

//工作台示例
const DesignerWorkbenchPannel: FC<TProp | any> = inject("store")(
  observer(({ store, setShowShelfModal, setSlotName }: ITDWP) => {
    const {
      languageStore: { lang, langCur },
      designerStore: {
        currentDesigner,
        changeCurrentWorkbench,
        currentWorkbench,
        currentSlotInfo,
        currentReactorSlotInfo,
        currentReagentsInfo,
      },
      workbenchStore: { getWorkbenchById },
      shelfStore: { allShelf },
      bottleStore: { allBottle },
    } = store;

    const [showLoading, setShowLoading] = useState<boolean>(true);

    const [rowList, setRowList] = useState<number[]>([]);

    const [columnList, setColumnList] = useState<number[]>([]);

    const [slotHeight, setSlotHeight] = useState<number>(0);

    const [slotWide, setSlotWide] = useState<number>(0);

    const [slotMargin, setSlotMargin] = useState<number>(0);

    const [slotShelf, setSlotShelf] = useState<any>(null);

    const [reactorSlotShelf, setReactorSlotShelf] = useState<any>(null);

    const [hoverPopName, setHoverPopName] = useState<string>("");

    useEffect(() => {
      setSlotHeight(BASEHEIGHT * RATE);
      setSlotWide(BASEWIDE * RATE);
      setSlotMargin(MARGIN * RATE);
    }, []);

    useEffect(() => {
      setSlotShelf(currentSlotInfo);
      setReactorSlotShelf(currentReactorSlotInfo);
    }, [currentSlotInfo, currentReactorSlotInfo]);

    useEffect(() => {
      const getWorkbench = async (data: any) => {
        const result: any = await getWorkbenchById(data);
        changeCurrentWorkbench(result);
        setShowLoading(false);
      };

      if (currentDesigner && !currentWorkbench?.id) {
        const { workbench } = currentDesigner;
        getWorkbench({ id: workbench });
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [currentDesigner]);

    useEffect(() => {
      if (currentWorkbench) {
        setShowLoading(false);
        const { row, column } = currentWorkbench;
        setRowList(createList(row || 0));
        setColumnList(createList(column || 0));
      }
    }, [currentWorkbench]);

    const slotClick = (slotName: string) => {
      setSlotName(slotName);
      setShowShelfModal(true);
    };

    const getBottleInfoById = (id: string): ITBottle | null => {
      let temp = null;
      allBottle.some((item) => {
        if (item.id === id) {
          temp = item;
          return true;
        }
        return false;
      });
      return temp;
    };

    const getShelfAndBottleInfo = (name: string): ITShelfBottle => {
      let temp = null;
      let tempBottle = null;
      allShelf.some((item) => {
        if (item.name === name) {
          temp = item;
          return true;
        }
        return false;
      });
      if (temp) {
        const { bottleType } = temp;
        tempBottle = getBottleInfoById(bottleType);
      }
      return {
        shelfInfo: temp,
        bottleInfo: tempBottle,
      };
    };

    return (
      <>
        {showLoading && <Spin />}
        {!showLoading && (
          <div className="workbenchplane">
            <div
              className="bord"
              style={{
                paddingLeft: slotMargin,
                paddingTop: slotMargin,
              }}
            >
              {rowList.map((rowItem) => {
                return (
                  <div
                    className="row"
                    key={rowItem}
                    style={{
                      marginBottom: slotMargin,
                      height: slotHeight,
                    }}
                  >
                    {columnList.map((colItem) => {
                      const slotName = `${ROWWORD[rowItem]}${colItem + 1}`;
                      // C3是用来添加反应器的，特殊颜色显示一下
                      // const isC3 = slotName === ReactionSlotName;

                      let hasMiniPlane = false;
                      let ShelfMiniPlaneParam: ITShelfBottle = {};
                      let shelfName = null;
                      if (slotShelf) {
                        let slotshelfInfo = slotShelf[slotName];
                        if (slotshelfInfo) {
                          hasMiniPlane = true;
                          const { shelf } = slotshelfInfo;
                          shelfName = shelf;
                          ShelfMiniPlaneParam = getShelfAndBottleInfo(shelf);
                        }
                      }

                      // 当有试剂和反应试剂时，禁止编辑
                      let hasReagent = false;
                      if (currentReagentsInfo) {
                        const reagentObjs = currentReagentsInfo[slotName];
                        if (reagentObjs) {
                          const keys = Object.keys(reagentObjs);
                          if (keys && keys.length) {
                            hasReagent = true;
                          }
                        }
                      }

                      const TipCont = () => (
                        <div
                          className={`hovertip ${
                            langCur === "en" ? "font20" : ""
                          }`}
                        >
                          {lang["langselectreagentrack"]}
                        </div>
                      );

                      return (
                        <Popover
                          open={hasMiniPlane && hoverPopName === slotName}
                          title={
                            <Space>
                              <Text strong>{slotName}</Text>
                              <Text type="secondary">{shelfName}</Text>
                            </Space>
                          }
                          content={<PopContent label={shelfName} />}
                          key={colItem}
                        >
                          <div
                            className={`slot designer ${
                              hasReagent ? "display" : ""
                            }`}
                            style={{
                              width: slotWide,
                              height: slotHeight,
                              marginRight: slotMargin,
                            }}
                            onClick={() => {
                              !hasReagent && slotClick(slotName);
                            }}
                            onMouseEnter={() => {
                              setHoverPopName(slotName);
                            }}
                            onMouseLeave={() => {
                              setHoverPopName("");
                            }}
                          >
                            {!hasMiniPlane && (
                              <div className="slotlabel">{slotName}</div>
                            )}
                            {hasMiniPlane && (
                              <ShelfMiniPlane
                                {...ShelfMiniPlaneParam}
                                slotName={slotName}
                              />
                            )}
                            {!hasReagent && <TipCont />}
                          </div>
                        </Popover>
                      );
                    })}
                  </div>
                );
              })}
            </div>
          </div>
        )}
      </>
    );
  })
);

const PopContent: FC<ITPopCont | any> = inject("store")(
  observer(({ store, label }: ITPopCont) => {
    const {
      languageStore: { lang, langCur },
      shelfStore: { allShelf },
      bottleStore: { allBottle },
      dictionaryStore: { getDictValuesByKey },
    } = store;

    if (!label) {
      return null;
    }

    let column = 0;
    let rows = 0;
    let volume = 0;

    let shelfInfo = null;
    let bottleInfo = null;
    let shelfType = "";

    const dicts: ITDictValue[] = getDictValuesByKey("reagentRackType");

    const getShelfTypeLabel = (type: string): string => {
      let labelstr = "";
      dicts.some(({ value, label, cnlabel }) => {
        if (value === type) {
          labelstr = label;
          if (langCur === "zhcn") {
            labelstr = cnlabel;
          }
          return true;
        }
        return false;
      });

      return labelstr;
    };

    allShelf.some((item: ITShelf) => {
      if (item.name === label) {
        column = item.column;
        rows = item.row;
        shelfInfo = item;
        shelfType = getShelfTypeLabel(shelfInfo.rackType);
        allBottle.some((bitem) => {
          if (bitem.id === item.bottleType) {
            volume = bitem.volume;
            bottleInfo = bitem;
            return true;
          }
          return false;
        });
        return true;
      }
      return false;
    });

    return (
      <Content>
        {/* <Row>
          <Col>
            <ShelfMiniPlane shelfInfo={shelfInfo} bottleInfo={bottleInfo} />
          </Col>
          <Col style={{marginLeft: 10}}>
            <PlaneImages shelfInfo={shelfInfo} />
          </Col>
        </Row> */}
        <ShelfMiniPlane shelfInfo={shelfInfo} bottleInfo={bottleInfo} />

        <Descriptions
          bordered
          size="small"
          column={1}
          style={{ marginTop: 20 }}
        >
          <Descriptions.Item label={lang["langracktype"]}>
            {shelfType}
          </Descriptions.Item>
          <Descriptions.Item label={lang["langcount"]}>
            {column * rows}
          </Descriptions.Item>
          <Descriptions.Item label={lang["langsinglevolume"]}>
            {volume}
            {lang["langmlunit"]}
          </Descriptions.Item>
          <Descriptions.Item label={lang["langtotalvolume"]}>
            {volume * column * rows}
            {lang["langmlunit"]}
          </Descriptions.Item>
        </Descriptions>
      </Content>
    );
  })
);

//试剂架选择弹窗
const ShelfSelectModal: FC<TProp | any> = inject("store")(
  observer(({ store, showShelfModal, close, slotName }: ITShelfModal) => {
    const {
      languageStore: { lang },
      shelfStore: { allShelf },
      designerStore: {
        saveSlotInfo,
        addEditDesignerLoading,
        removeSlotInfo,
        currentSlotInfo,
      },
    } = store;

    const [selectValue, setSelectValue] = useState<string>("");

    function sortLabwareArray(arr: any) {
      return [...arr].sort((a, b) =>
        a.label.localeCompare(b.label, undefined, {
          numeric: true, // 启用数字识别
          sensitivity: "base", // 忽略大小写和音调差异
        })
      );
    }

    const options = useMemo(() => {
      let list: any[] = [{ label: lang["langempty"], value: "" }];
      if (allShelf && allShelf.length) {
        allShelf.forEach((item) => {
          // 过滤反应架
          list.push({
            label: item.name,
            value: item.name,
          });
        });
      }
      return sortLabwareArray(list);
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [allShelf]);

    useEffect(() => {
      if (currentSlotInfo) {
        const slotInfo = currentSlotInfo[slotName];
        if (slotInfo) {
          const { shelf } = slotInfo;
          setSelectValue(shelf);
        }
      }
    }, [currentSlotInfo, slotName]);

    const onSelect = (data: string) => setSelectValue(data);

    const closeModal = () => {
      setSelectValue("");
      close();
    };

    const selectShelf = () => {
      if (selectValue) {
        saveSlotInfo({
          [slotName]: { shelf: selectValue },
        });
      } else {
        removeSlotInfo(slotName);
      }
      closeModal();
    };

    return (
      <Modal
        title={slotName}
        open={showShelfModal}
        onOk={selectShelf}
        onCancel={closeModal}
        destroyOnClose={true}
        confirmLoading={addEditDesignerLoading}
      >
        <Select
          style={{ width: "100%" }}
          defaultValue={null}
          value={selectValue}
          onSelect={onSelect}
        >
          {!!options.length &&
            options.map(({ label, value }: any, index: number) => (
              <Option value={value} key={index}>
                <Popover
                  placement="left"
                  title={label}
                  content={<PopContent label={value} />}
                >
                  <div>{label}</div>
                </Popover>
              </Option>
            ))}
        </Select>
      </Modal>
    );
  })
);

const ReactorSelectModal: FC<TProp | any> = inject("store")(
  observer(({ store, slotName, showModal, close }: ITRSProp) => {
    const {
      languageStore: { lang },
      shelfStore: { allShelf },
      designerStore: {
        saveReactorSlotInfo,
        addEditDesignerLoading,
        removeReactorSlotInfo,
        currentReactorSlotInfo,
      },
    } = store;

    const [selectValue, setSelectValue] = useState<string>("");

    const onSelect = (data: string) => setSelectValue(data);

    const options = useMemo(() => {
      let list: any[] = [{ label: lang["langempty"], value: "" }];
      if (allShelf && allShelf.length) {
        allShelf.forEach((item) => {
          // 过滤反应架
          if (item.rackType === "reactor") {
            list.push({
              label: item.name,
              value: item.name,
            });
          }
        });
      }
      return list;
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [allShelf]);

    useEffect(() => {
      if (currentReactorSlotInfo) {
        const slotInfo = currentReactorSlotInfo[slotName];
        if (slotInfo) {
          const { shelf } = slotInfo;
          setSelectValue(shelf);
        }
      }
    }, [currentReactorSlotInfo, slotName]);

    const closeModal = () => {
      setSelectValue("");
      close();
    };

    const selectReactor = () => {
      if (selectValue) {
        saveReactorSlotInfo({
          [slotName]: { shelf: selectValue },
        });
      } else {
        removeReactorSlotInfo();
      }
      closeModal();
    };

    return (
      <Modal
        title={slotName}
        open={showModal}
        onOk={selectReactor}
        onCancel={closeModal}
        destroyOnClose={true}
        confirmLoading={addEditDesignerLoading}
      >
        <Select
          style={{ width: "100%" }}
          defaultValue={null}
          value={selectValue}
          onSelect={onSelect}
        >
          {!!options.length &&
            options.map(({ label, value }: any, index: number) => (
              <Option value={value} key={index}>
                <Popover
                  placement="left"
                  title={label}
                  content={<PopContent label={value} />}
                >
                  <div>{label}</div>
                </Popover>
              </Option>
            ))}
        </Select>
      </Modal>
    );
  })
);

const DesignerShelf: FC<TProp | any> = ({ store }: TProp): JSX.Element => {
  const {
    languageStore: { lang },
    designerStore: { currentDesigner, getDesignerInfo, updateDesigner },
    shelfStore: { getAllShelf, allShelf },
    bottleStore: { getAllBottle, allBottle },
  } = store;

  const navigate = useNavigate();
  const params = useParams();

  // 是否显示试剂架选择弹窗
  const [showShelfModal, setShowShelfModal] = useState<boolean>(false);

  // 是否显示反应架选择弹窗
  //   const [showReactModal, setShowReactModal] = useState<boolean>(false);

  const [slotName, setSlotName] = useState<string>("");

  const closeShelfModal = () => {
    setSlotName("");
    setShowShelfModal(false);
  };

  //   const closeReactorModal = () => {
  //     setSlotName("");
  //     setShowReactModal(false);
  //   };

  useEffect(() => {
    if (!allBottle.length) {
      getAllBottle();
    }
    if (!allShelf.length) {
      getAllShelf();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    const { id } = params;
    if (id) {
      getDesignerInfo({ id });
    }

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [params]);

  const clickPrev = () => {
    navigate(`/designer/add/${params.id}`);
  };

  const clickNext = async () => {
    // 判断是否添加了试剂架和反应架

    const { slotShelf, reactorSlotShelf, step, id } = currentDesigner || {};
    if (!slotShelf || !reactorSlotShelf) {
      message.error(lang["langdesignernext1"]);
      return;
    }
    if (step && step < 2) {
      await updateDesigner({
        id,
        step: 2,
      });
    }

    navigate(`/designer/reagents/${params.id}`);
  };

  return (
    <Content className="mainLayout">
      {/* 步骤 */}
      <StepTop currentStep={1} />
      <Divider />

      {/* 工作台示例 */}
      <DesignerWorkbenchPannel
        setShowShelfModal={setShowShelfModal}
        // setShowReactModal={setShowReactModal}
        setSlotName={setSlotName}
      />

      <Row>
        <Col span={24} style={{ textAlign: "center", marginTop: 20 }}>
          <Space>
            <Button onClick={clickPrev}>{lang["langprev"]}</Button>
            <Button type="primary" onClick={clickNext}>
              {lang["langnext"]}
            </Button>
          </Space>
        </Col>
      </Row>

      {/* 试剂架选择弹窗 */}
      <ShelfSelectModal
        showShelfModal={showShelfModal}
        close={closeShelfModal}
        slotName={slotName}
      />

      {/* 反应架选择弹窗 */}
      {/* <ReactorSelectListModal
        close={closeReactorModal}
        slotName={slotName}
        showReactModal={showReactModal}
      /> */}
    </Content>
  );
};

export default inject("store")(observer(DesignerShelf));
